use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;

// 享元对象 `Flyweight` 结构体，包含内部状态 `intrinsic_state`。
struct Flyweight {
    intrinsic_state: String,
}

impl Flyweight {
    // 操作方法 `operation()`，接受外部状态 `extrinsic_state` 并返回格式化的信息。
    fn operation(&self, extrinsic_state: &str) -> String {
        format!(
            "Intrinsic: {}, Extrinsic: {}",
            self.intrinsic_state, extrinsic_state
        )
    }
}

// 享元工厂 `FlyweightFactory` 结构体，管理和创建享元对象。
struct FlyweightFactory {
    flyweights: HashMap<String, Rc<RefCell<Flyweight>>>, // 使用哈希表存储享元对象
}

impl FlyweightFactory {
    // 构造函数 `new()`，初始化享元工厂对象。
    fn new() -> Self {
        Self {
            flyweights: HashMap::new(),
        }
    }

    // 获取享元对象的方法 `get_flyweight()`，根据给定的 `key` 获取对应的享元对象。
    // 如果不存在，则创建新的享元对象并存储在哈希表中。
    fn get_flyweight(&mut self, key: &str) -> Rc<RefCell<Flyweight>> {
        self.flyweights
            .entry(key.to_string())
            .or_insert_with(|| {
                Rc::new(RefCell::new(Flyweight {
                    intrinsic_state: key.to_string(),
                }))
            })
            .clone() // 返回克隆的 `Rc<RefCell<Flyweight>>`，确保引用计数正确
    }
}

// 主函数入口 `main()`，演示享元模式的使用。
pub fn main() {
    let mut factory = FlyweightFactory::new(); // 创建享元工厂对象

    // 获取享元对象，并传入外部状态进行操作
    let flyweight1 = factory.get_flyweight("State1");
    let flyweight2 = factory.get_flyweight("State2");
    let flyweight3 = factory.get_flyweight("State1"); // 重复获取相同的享元对象

    // 打印每个享元对象的操作结果，包括内部状态和传入的外部状态
    println!("{}", flyweight1.borrow().operation("Extrinsic1"));
    println!("{}", flyweight2.borrow().operation("Extrinsic2"));
    println!("{}", flyweight3.borrow().operation("Extrinsic3"));
}
